<template>
  <el-container>
    <div>
      <div id="graphArea"></div>
      <div class="custom-search">
        <div class="right-content">
          <!-- <el-input
            v-model="searchInput"
            placeholder="Input ItemNumber"
            style="height: 40px; margin-top: 5px"
            class="group-input"
          ></el-input> -->
          <el-select v-if="!specList || specList.length == 0"
            v-model="searchInput"
            filterable
            remote
            reserve-keyword
            placeholder="Input"
            :remote-method="findItem"
            :loading="searchLoading"
            style="margin-right: 20px; width : 400px"
          >
            <el-option
              v-for="item in searchOptions"
              :key="item.itemnumber"
              :label="item.short_name"
              :value="item.itemnumber"
            >
            </el-option>
          </el-select>
          <el-tag
            v-for="tag in specList"
            :key="tag"
            closable
            size="mini"
            style="margin-top: 20px; margin-right: 15px"
            @close="handleClose(tag)"
          >
            {{ tag }}
          </el-tag>
          <el-button
            type="primary"
            icon="el-icon-search"
            @click="searchByItem"
            style="height: 40px; margin-top: 10px"
            >Search</el-button
          >
        </div>
      </div>
      <div class="custom-menu" style="width: 80px">
        <div><a @click="addList">Add </a></div>
        <div><a @click="newPage">Open link </a></div>
      </div>
    </div>
  </el-container>
</template>

<script>
import vis, { Network } from "vis-network/dist/vis-network.min.js";
import "vis-network/dist/dist/vis-network.min.css";
import service from "./service";
import { Loading } from "element-ui";
import $ from "jquery";

export default {
  data() {
    return {
      nodes: [],
      edges: [],
      currentId: "before",
      specList: [],
      itemMap: {},
      //specMap:{},
      searchInput: "",
      searchLoading: false,
      searchOptions:[],
      specIdList:[]
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    async findByspecs(){
      if(this.specList.length == 0){ return }
      let response = await service.findByspecs(this.specList);
      return response;
    },
    async findItem(searchInput){
      this.searchLoading =true;
      let response = await service.findItemByremote(searchInput);
      this.searchOptions = response.data;
      this.searchLoading =false;
    },
    async searchByItem() {
      let response;
      if(this.specList.length != 0){
        response = await service.findByspecs(this.specIdList);
        let loadingInstance1 = Loading.service({
          fullscreen: true,
          text: "Loading",
        });
        this.processSpecsResponse(response);
        this.execute();
        loadingInstance1.close();
      }else{
        response = await service.searchByItemNumber(this.searchInput);
        let loadingInstance1 = Loading.service({
          fullscreen: true,
          text: "Loading",
        });
        this.processResponse(response);
        this.execute();
        loadingInstance1.close();
      }
      
    },
    async init() {
      let loadingInstance1 = Loading.service({
        fullscreen: true,
        text: "Loading",
      });
      let response = await service.findItemGraph();
      this.processResponse(response);
      this.execute();
      loadingInstance1.close();
    },
    processSpecsResponse(response){
      let arryNew = [];
      if (response.data.nodes) {
        response.data.nodes.forEach((row) => {
          this.itemMap[row.id] = row;
          row.size = 30;
          if (row.image) {
            row.shape = "circularImage";
          } else {
            row.shape = "dot";
          }
          if(row.type == "spec"){
            row.size = 15
          }
          if (row.group == "main") {
            row.size = 30;
          }
          if(row.type == "item"){
            row.size = 40
          }
          arryNew.push(row);
        });
      }
      this.nodes = arryNew;
      this.edges = response.data.edges;
    },
    processResponse(response){
      this.specIdList=[];
      this.specList=[];
      let arryNew = [];
      if (response.data.nodes) {
        response.data.nodes.forEach((row) => {
          this.itemMap[row.id] = row;
          row.size = 30;
          if (row.image) {
            row.shape = "circularImage";
          } else {
            row.shape = "dot";
          }
          if(row.type == "spec"){
            row.size = 20
          }
          if(row.type == "item"){
            row.size = 40
          }
          if (row.group == "main") {
            row.x = 0;
            row.y = 0;
            row.size = 60;
            row.physics = false;
          }
          if (row.type == "category") {
            row.x = 800;
            row.y = 0;
            row.physics = false;
            row.color ='green';
          }
          if (row.type == "brand") {
            row.x = 0;
            row.y = 800;
            row.physics = false;
            row.color ='green';
          }
          if (row.type == "nobrand") {
            row.x = 0;
            row.y = -800;
            row.physics = false;
            row.color ='green';
          }
          if (row.type == "nocategory") {
            row.x = -800;
            row.y = 0;
            row.physics = false;
            row.color ='green';
          }
          arryNew.push(row);
        });
      }
      this.nodes = arryNew;
      this.edges = response.data.edges;
    },
    execute() {
      var data = {
        nodes: this.nodes,
        edges: this.edges,
      };
      //let data = { nodes: new vis.DataSet(response.data.nodes), edges: new vis.DataSet(response.data.edges) }
      var options = {
        nodes: {
          borderWidth: 0,
          size: 25,
          font: {
            size: 30,
          },
        },
        // edges:{
        //   smooth: {
        //     type: "continuous",
        //   },
        //   color: "lightgray",
        // },
        edges: {
          width: 0.01,
          font: {
            size: 0,
            //color: 'green',
          },
          color: {
            //inherit: 'to',
            opacity: 0.4,
            //color: '#cccccc',
            highlight: "#ff0000",
            hover: "#ff0000",
          },
          selectionWidth: 0.05,
          hoverWidth: 0.05,
          arrows: {
            from: {},
            to: {
              enabled: true,
              scaleFactor: 0.5,
            },
          },
          smooth: {
            enabled: true,
            type: "continuous",
            roundness: 0.5,
          },
        },
        physics: {
          stabilization: false,
          solver: "barnesHut",
          barnesHut: {
            gravitationalConstant: -60000,
            springConstant: 0.1,
            springLength: 200,
          },
          forceAtlas2Based: {
            gravitationalConstant: -800,
            centralGravity: 0.001,
            springLength: 230,
            springConstant: 0.18,
          },
          timestep: 0.4,
        },
        interaction: {
          tooltipDelay: 200,
          hover: true,
          hideEdgesOnDrag: true,
          selectable: true,
          navigationButtons: true,
          //selectConnectedEdges: false,
        },
      };
      this.network = new Network(
        document.querySelector("#graphArea"),
        data,
        options
      );
      this.network.on("selectNode", function (e) {
        e.edges.forEach((edge) => {
          this.body.data.edges.update({
            id: edge,
            font: {
              size: 20,
            },
          });
        });
      });
      this.network.on("deselectNode", function (e) {
        e.previousSelection.edges.forEach((edge) => {
          this.body.data.edges.update({
            id: edge,
            font: {
              size: 0,
            },
          });
        });
      });
      this.network.on("click", (e) => {
        //let row = this.itemMap[e.nodes[0]]
        if (!$(".custom-menu").is(":hidden")) {
          $(".custom-menu").hide();
        }
      });
      this.network.on("doubleClick", async (e) => {
        let row = this.itemMap[e.nodes[0]];
        if(row.type == 'item'){
          let loadingInstance1 = Loading.service({
            fullscreen: true,
            text: "Loading",
          });
          let response = await service.searchByItemNumber(row.itemnumber);
          this.processResponse(response);
          this.execute();
          loadingInstance1.close();
        }else if(row.type == 'spec'){
          let current = this.itemMap[e.nodes[0]]
          if (this.specList.indexOf(current.name) == -1) {
            this.specList.push(current.name);
            this.specIdList.push(current.type + '/' + current.key);
          }
        }else{
          this.$message("敬请期待");
        }
        
      });
      this.network.on("oncontext", (params) => {
        var nodeId = this.network.getNodeAt(params.pointer.DOM);
        if (nodeId) {
          params.event.preventDefault();
          this.currentId = nodeId;
          $(".custom-menu").finish().toggle(100);
          $(".custom-menu").css({
            top: params.pointer.DOM.y + "px",
            left: params.pointer.DOM.x + "px",
          });
        }
      });
       this.network.on('hoverNode',async (params) =>{
         if(params.node.indexOf("item/") == 0){
           let response = await service.getItemDetail(this.itemMap[params.node].itemnumber);
           let src = '';
           src = "<a style='color:red;'> Tips: Double click select item; right click add spec to filter or link to item page.</a><br/>"+"Name: " + response.data.name + ", <br/>" + "ItemNumber" + ": " + response.data.itemnumber + ", <br/>" +"url" + ": " + response.data.url;
           this.network.clustering.updateClusteredNode(params.node, {
                title: src
               });
         }
      });
      setTimeout(() => {
        this.network.stopSimulation();
      }, 10000);
    },
    
    addList: function () {
      if (this.specList.length < 10) {
        if (this.currentId.indexOf("spec/") == 0) {
          let current = this.itemMap[this.currentId]
          if (this.specList.indexOf(current.name) == -1) {
            this.specList.push(current.name);
            this.specIdList.push(current.type + '/' + current.key);
          } else {
            this.$message("Spec existing");
          }
        } else {
          this.$message("This node is not spec");
        }
      } else {
        this.$message("Add up to 10");
      }

      if (!$(".custom-menu").is(":hidden")) {
        $(".custom-menu").hide();
      }
    },
    newPage: function () {
      if (this.currentId) {
        let row = this.itemMap[this.currentId];
        if (row.categories.indexOf("item") > -1) {
          window.open(row.url, "_blank");
          if (!$(".custom-menu").is(":hidden")) {
            $(".custom-menu").hide();
          }
        }else{
          this.$message("This node is not item");
        }
      }
    },
    handleClose(tag) {
      this.specIdList.splice(this.specList.indexOf(tag), 1);
      this.specList.splice(this.specList.indexOf(tag), 1);
      if(this.specList.length == 0){
        this.init()
      }
    },
  },
};
</script>

<style>
#app {
  font-family: Helvetica, sans-serif;
  text-align: center;
}
#graphArea {
  width: 100%;
  position: absolute;
  top: 50px;
  bottom: 0px;
  left: 0px;
}
.header-wrapper {
  padding: 10px 20px;
  overflow: hidden;
  display: flex;
  justify-content: space-between;
}
.right-content {
  display: flex;
  justify-content: flex-end;
}
.group-input {
  margin: 0 1rem;
}
.logo-wrapper {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 180px;
  cursor: pointer;
  padding-left: 22px;
}
.main {
  background-color: #f0f2f5;
}
.box-card {
  width: 99%;
}
.el-row {
  margin-bottom: 10px;
}
.el-col {
  border-radius: 4px;
}
/* .el-table--mini, .el-table--small, .el-table__expand-icon {
    font-size: 0.4rem;
} */

.custom-search {
  position: absolute;
  padding: 5px 0px;
  left: 20px;
}

.custom-search div {
  padding: 5px 0px;
  text-align: center;
}

.custom-menu {
  position: absolute;
  padding: 5px 0px;
  background-color: rgb(154, 160, 167);
  top: 100px;
  left: 100px;
  z-index: 9999;
  display: none;
}

.custom-menu div {
  padding: 5px 0px;
  text-align: center;
}
.custom-menu div a {
  font-size: 14px;
  color: rgb(255, 255, 255);
}
.custom-menu div a:hover,
.custom-menu div a:active {
  cursor: pointer;
  color: orange;
}
</style>
